AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile( "shared.lua" )

include('shared.lua')

-- Variables
	ENT.AttackTime = 0
	ENT.AttackRangeTime = 0
	ENT.Dead = false
	
	ENT.DeathSounds = {}
	ENT.PainSounds = {}

-- Fight + Chase Schedules

local schdChase = ai_schedule.New( "AIFighter Chase" )
	
	schdChase:EngTask( "TASK_GET_PATH_TO_ENEMY", 0 )
   	schdChase:EngTask( "TASK_RUN_PATH_TIMED", 0.2 )
    schdChase:EngTask( "TASK_WAIT_", 0.2 ) 
	
local schdAttack = ai_schedule.New( "AIFighter Attack" )

	schdAttack:EngTask( "TASK_STOP_MOVING", 			0 )

-- Standard Schedule

function ENT:SelectSchedule()
	
	self:UpdateEnemy( self:FindEnemy() )

	local enemy = self:GetEnemy()
	
	if enemy and enemy:IsValid() then
	
		local spos = self:GetPos()
		local epos = enemy:GetPos()
		local dist = spos:Distance( epos )
		
		if dist < 1000 and dist > 50 then
		
			self:AttackEnemyRange()
			
		elseif dist < 50 then
		
			self:AttackEnemyMelee()
			
		else
			
			self:ChaseEnemy()
			
		end
		
	end
	
end
	
-- CUSTOM TASKS

function ENT:ChaseEnemy()

	self:StartSchedule( schdChase )
	
end

function ENT:AttackEnemyRange()

	self:RefreshRotation()

	if self.AttackRangeTime > CurTime() then return end
	
	self.AttackRangeTime = CurTime() + 3
	
	local enemy = self:GetEnemy()
	
	if enemy and enemy:Alive() and enemy:IsPlayer() and not enemy.IsStunned then
	
		self:StartSchedule( schdAttack )

		local ent = ents.Create( "stun_pulse" )
			ent:SetPos(self:GetPos() + Vector( 0, 0, 10 ))
			ent:Spawn()
			ent:SetVelocity( self:GetAimVector() * 3500 )
			ent:SetOwner( self )
			ent:SetColor( 173,255,106,100 )
			
	end
	
end

function ENT:AttackEnemyMelee()

	local enemy = self:GetEnemy()
	local epos = enemy:GetPos()
	local spos = self:GetPos()
	local dist = epos:Distance( spos )
	
	if enemy and enemy:IsValid() and dist < 100 and self.AttackTime < CurTime() then

		self.AttackTime = CurTime() + 3
		
		local ed = EffectData()
			ed:SetEntity( enemy )
			ed:SetOrigin( epos + Vector( 0, 0, 40 ) )
		util.Effect( "playerhit", ed, true, true )
		
		enemy:TakeDamage( self.Damage, self )
		
		-- put in sound stuff
		
	else
	
		-- put in miss stuff
		
	end

end

function ENT:RefreshRotation()

	local enemy = self:GetEnemy()
	
	local epos = enemy:GetPos()
	local spos = self:GetPos()
	
	local sangles = self:GetAngles()
	
	local dy = ( spos.y - epos.y )
	local dx = ( spos.x - epos.x ) 
	local tan = dy / dx
	
	local edirection = math.atan( tan )
	local edirection = math.Rad2Deg( edirection )
	
	if dx > 0 then edirection = edirection + 180 end
	
	self:SetAngles( Angle( sangles.p, edirection, sangles.r ) )
	
end

function ENT:FindEnemy() -- Stolen code from Zombie Onslaught -- Sorry Rambo_6 :V

	if GetTeamSize( 10 ) < 1 then
		
		return NULL
		
	else
	
		local enemy = table.Random( GetPlayersTB( 1 ) )
		local dist = 99999
		
		for k,v in pairs( GetPlayersTB( 1 ) ) do
			local compare = v:GetPos():Distance( self.Entity:GetPos() )
			if compare < dist and v:Alive() and not v.IsStunned then
				enemy = v
				dist = compare
			end
		end
		
		return enemy
		
	end
	
end

function ENT:UpdateEnemy( enemy )

	if enemy and enemy:IsValid() and enemy:Alive() then
		
		self:SetEnemy( enemy, true ) 
		self:UpdateEnemyMemory( enemy, enemy:GetPos() ) 
		
	else
		
		self:SetEnemy( NULL )
		
	end

end

function ENT:Voice( sound )

	--local sound = table.Random( sound )

	--self:EmitSound( Sound( sound ), 100, math.random( 90, 100 ) )
	
end

function ENT:RemoveRagdoll( ragdoll, index )

	ragdoll.alpha = 255
	
	local function Think()
	
		if ragdoll and ragdoll:IsValid() then
		
			ragdoll.alpha = math.Approach( ragdoll.alpha, 0, FrameTime() * 20 )
			
			ragdoll:SetColor( 255, 255, 255, ragdoll.alpha )
			
			if ragdoll.alpha == 0 then
			
				ragdoll:Remove()
				hook.Remove( "Think", "LightThink"..index )
				
			end
		
		else
		
			hook.Remove( "Think", "LightThink"..index )
			
		end
	
	end
	hook.Add("Think", "LightThink"..index, Think)

end

function ENT:Die( attacker )

	if self.Dead then return end
	
	self.Dead = true
	
	attacker.WraithKilled = attacker.WraithKilled + 1
	
	self:Voice( self.DeathSounds )
	
	local ragdoll = ents.Create( "prop_ragdoll" )
		ragdoll:SetPos( self:GetPos() )
		ragdoll:SetModel( self:GetModel() )
		ragdoll:Spawn()
		ragdoll:Activate()
		ragdoll:GetPhysicsObject():SetVelocity(Vector(0, 500, 0))
		
		local index = ragdoll:EntIndex()
		timer.Create("solidcheck"..index, 2, 1, function() ragdoll:SetSolid(SOLID_NONE) end)
		
		self:RemoveRagdoll( ragdoll, index )
		
	self:Remove()
	
end

function ENT:OnTakeDamage( dmg )

	if not dmg:GetAttacker():IsPlayer() then return end
	
	self:SetHealth( math.Clamp( self:Health() - dmg:GetDamage(), 0, 100 ) )
	
	if self:Health() <= 0 then
	
		self:Die( dmg:GetAttacker() )
		
	elseif math.random( 1, 3 ) == 3 then
	
		self:Voice( self.PainSounds )
		
	end
	
end

function ENT:Initialize()

	self:SetModel( "models/Police.mdl" )
	self:SetHealth( 200 )
	
	self:SetHullType( HULL_HUMAN );
	self:SetHullSizeNormal();
	
	self:SetSolid( SOLID_BBOX )
	self:SetMoveType( MOVETYPE_STEP )
	
	self:CapabilitiesAdd( CAP_MOVE_GROUND | CAP_OPEN_DOORS | CAP_ANIMATEDFACE | CAP_TURN_HEAD | CAP_USE_SHOT_REGULATOR | CAP_AIM_GUN )
	
	self:SetMaxYawSpeed( 5000 )
		
	self:Give( "weapon_mp5" )
	
	self:UpdateEnemy( self:FindEnemy() )

end